home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Modules / BackSpaceModules / Source / Charender / DN3DString.m < prev    next >
Encoding:
Text File  |  1994-02-15  |  4.0 KB  |  182 lines

  1. /***************************************************
  2. **
  3. **    DN3DString.m
  4. **
  5. **    By Brian Hobbs (brian@ny.shl.com)
  6. **
  7. **    This class actually creates the 3D text string.
  8. **    It's performed through the PSW_tracestring call.
  9. **    The rest of the algorithm is massaging the bezier
  10. **    control points into the proper format to be 
  11. **    recognized by RiPatchMesh, which physically
  12. **    creates the text in Renderman.
  13. **
  14. **    This code is public domain.  Feel free to use
  15. **    it in any way you wish.  I'd like to see any 
  16. **    changes you make, tho.
  17. **
  18. ****************************************************/
  19.  
  20. #import "DN3DString.h"
  21. #import "CharPaths.h"
  22. #import <ri/ri.h>
  23.  
  24. #define SCALE 100
  25.  
  26. #define MOVETO    -1000
  27. #define LINETO    -2000
  28. #define CURVETO -3000
  29. #define CLOSE    -4000
  30. #define EMPTY    -5000
  31.  
  32. @implementation DN3DString:N3DShape
  33.  
  34. - init
  35. {
  36.     int i;
  37.     [super init];
  38.     
  39.     resolution[0] = 35;
  40.     resolution[1] = 1;
  41.     
  42.     textFont = (char *)NXZoneMalloc([self zone], sizeof(char) * 256);
  43.     for (i=0; i<256; i++)
  44.         textFont[i] = 0;
  45.         
  46.     return self;
  47. }
  48.  
  49. - setResolution:(float)newRes
  50. {
  51.     resolution[0] = newRes;
  52.     return self;
  53. }
  54.  
  55. - setTextString:(const char *)aString andFont:(const char *)aFont
  56. {
  57.     float pathStack[1000];
  58.     int *numCurves, *counter;    
  59.     int i,j,k;
  60.  
  61.     for (i=0; i<1000; i++)
  62.         pathStack[i] = EMPTY;
  63.  
  64.     PSW_tracestring(aString, aFont, &(pathStack[0]));
  65.     
  66.     if (mesh){
  67.         for (i=0; i<numPaths; i++)
  68.             NXZoneFree([self zone], mesh[i]);
  69.         NXZoneFree([self zone], mesh);
  70.     }
  71.     if (numCtrlPoints)
  72.         NXZoneFree([self zone], numCtrlPoints);
  73.  
  74.     numPaths = i = 0;
  75.     
  76.     while (pathStack[i] != EMPTY){        // find the number of paths
  77.         if (pathStack[i] == CLOSE)
  78.             numPaths++;
  79.         i++;
  80.     }
  81.         
  82.     mesh = (RtFloat **)NXZoneMalloc([self zone], sizeof(RtFloat *) * numPaths);
  83.     numCtrlPoints = (int *)NXZoneMalloc([self zone], sizeof(int) * numPaths);
  84.     numCurves = (int *)NXZoneMalloc([self zone], sizeof(int) * numPaths);
  85.     counter = (int *)NXZoneMalloc([self zone], sizeof(int) * numPaths);
  86.     
  87.     for (i=0; i<numPaths; i++){
  88.         numCtrlPoints[i] = 0;
  89.         numCurves[i] = 0;
  90.         counter[i] = 0;
  91.     }
  92.     
  93.     i = j = 0;
  94.     
  95.     // find the number of bezier control points of each path...
  96.     
  97.     while (pathStack[i] != EMPTY){
  98.         if (pathStack[i] == LINETO || pathStack[i] == CURVETO)
  99.             numCurves[j]++;
  100.         if (pathStack[i] == CLOSE){
  101.             numCtrlPoints[j] = (4 + ((numCurves[j] - 1) * 3));
  102.             mesh[j] = (RtFloat *)NXZoneMalloc([self zone], sizeof(RtFloat) * (numCtrlPoints[j] * 2 * 3));
  103.             j++;
  104.         }
  105.         i++;
  106.     }
  107.     
  108.     j = 0;
  109.     
  110.     for (k = 0; k < 2; k++){
  111.         i = j = 0;        
  112.         while ((pathStack[i] != EMPTY) && (j != numPaths)){        // then properly fill the mesh
  113.             switch((int)pathStack[i]){
  114.                 case LINETO :
  115.                     mesh[j][counter[j]] = (float)pathStack[i-2] / SCALE;
  116.                     mesh[j][++counter[j]] = (float)pathStack[i-1] / SCALE;
  117.                     mesh[j][++counter[j]] = (float)k / 4.0;
  118.                     mesh[j][++counter[j]] = (float)pathStack[i-2] / SCALE;
  119.                     mesh[j][++counter[j]] = (float)pathStack[i-1] / SCALE;
  120.                     mesh[j][++counter[j]] = (float)k / 4.0;
  121.                     counter[j]++;
  122.                     break;
  123.                 case CLOSE :
  124.                     j++;
  125.                     break;
  126.                 case MOVETO:
  127.                 case CURVETO:
  128.                     break;                
  129.                 default : 
  130.                     mesh[j][counter[j]] = (float)pathStack[i] / SCALE;
  131.                     counter[j]++;
  132.                     if (((counter[j] + 1) % 3) == 0){
  133.                         mesh[j][counter[j]] = (float)k / 4.0;
  134.                         counter[j]++;
  135.                     }
  136.                     break;
  137.             }
  138.             i++;
  139.         }
  140.     }
  141.     
  142.     NXZoneFree([self zone], numCurves);
  143.     NXZoneFree([self zone], counter);
  144.     
  145.     return self;
  146. }
  147.  
  148. - setTextFont:(const char *)aFont
  149. {
  150.     strcpy(textFont, (char *)aFont);
  151.     
  152.     return self;
  153. }
  154.  
  155. - setTextString:(const char *)aString
  156. {
  157. // assumes setTextFont previously invoked
  158.  
  159.     [self setTextString:aString andFont:(const char *)textFont];
  160.     
  161.     return self;
  162. }
  163.  
  164. - renderSelf:(RtToken)context
  165. {
  166.     int i;
  167.     
  168.     RiBasis(RiBezierBasis, RI_BEZIERSTEP, RiBezierBasis, RI_BEZIERSTEP);
  169.     RiGeometricApproximation( RI_TESSELATION, RI_PARAMETRIC, resolution, RI_NULL );
  170.  
  171. //    RiRotate(-90,1,0,0);
  172.     RiTranslate(0,0,-0.5);
  173.     RiScale(0.15, 0.15, 0.15);
  174.  
  175.     for (i=0; i<numPaths; i++)
  176.         RiPatchMesh(RI_BILINEAR, (RtInt)numCtrlPoints[i], RI_PERIODIC, (RtInt)2, RI_NONPERIODIC, RI_P, (RtPointer)mesh[i], RI_NULL);
  177.     
  178.     return self;
  179. }
  180. @end
  181.   
  182.